﻿package mortal.game.scene3D.ai.ais
{
    import Message.BroadCast.*;
    import com.gengine.core.frame.*;
    import extend.language.*;
    import flash.events.*;
    import flash.geom.*;
    import frEngine.event.*;
    import mortal.game.*;
    import mortal.game.cache.*;
    import mortal.game.control.subControl.*;
    import mortal.game.manager.*;
    import mortal.game.mvc.*;
    import mortal.game.rules.*;
    import mortal.game.scene3D.ai.*;
    import mortal.game.scene3D.ai.base.*;
    import mortal.game.scene3D.ai.data.*;
    import mortal.game.scene3D.events.*;
    import mortal.game.scene3D.layer3D.*;
    import mortal.game.scene3D.layer3D.utils.*;
    import mortal.game.scene3D.map3D.AstarAnyDirection.data.*;
    import mortal.game.scene3D.player.entity.*;
    import mortal.game.scene3D.player.info.*;
    import mortal.game.scene3D.util.*;
    import mortal.game.utils.*;
    import mortal.game.view.common.cd.*;
    import mortal.game.view.copy.petBreak.*;
    import mortal.game.view.skill.*;
    import mortal.mvc.core.*;

    public class FollowFightBossToDeadAI extends AICommand
    {
        private var _timer:FrameTimer;
        private var _skill:SkillInfo;
        private var _skillTobeUseFirtst:SkillInfo;
        private var _targetEntity:IEntity;
        private var _targetEntityInfo:EntityInfo;
        private var _isCancelAll:Boolean = false;
        private var _aiList:Array;
        private var _curAI:IAICommand;
        private var _cd:ICDData;
        private var roleInfo:SEntityInfo;

        public function FollowFightBossToDeadAI()
        {
            this._aiList = [];
            return;
        }// end function

        public function get curAI() : IAICommand
        {
            return this._curAI;
        }// end function

        public function set curAI(param1:IAICommand) : void
        {
            this._curAI = param1;
            return;
        }// end function

        override public function start(param1:Function = null) : void
        {
            this.roleInfo = Cache.instance.role.roleEntityInfo.entityInfo;
            super.start(param1);
            this.updateSkill();
            this._targetEntity = ThingUtil.selectEntity;
            this._targetEntityInfo = this._targetEntity.entityInfo;
            this._cd = Cache.instance.cd.getCDData(this._skill, CDDataType.skillInfo);
            if (this._targetEntity == null || this._skill == null || this._cd == null)
            {
                this.stop();
                return;
            }
            this._timer = new FrameTimer(2);
            this._timer.addListener(TimerType.ENTERFRAME, this.onEnterFrameHandler);
            this._timer.start();
            FrEventDispatcher.instance.proxyAddEventListener(this._targetEntity, PlayerEvent.ENTITY_DEAD, this.onPlayerDeadHandler, false, 0, true);
            FrEventDispatcher.instance.proxyAddEventListener(RolePlayer.instance, PlayerEvent.ENTITY_DEAD, this.onEntityDead, false, 0, true);
            this._targetEntityInfo.addEventListener(EntityInfoEventName.UpdateForce, this.forceUpdated);
            this._targetEntityInfo.addEventListener(EntityInfoEventName.UpdateFightMode, this.fightModeUpdated);
            NetDispatcher.addCmdListener(ServerCommand.BufferUpdate, this.buffUpdateHandler);
            this.onEnterFrameHandler();
            return;
        }// end function

        private function fightModeUpdated(param1 = null) : void
        {
            if (this._targetEntity == null)
            {
                this.stop();
                return;
            }
            var _loc_2:* = EntityDictionary.isEntityFit(this._targetEntity, null, EntityRelationUtil.ENEMY, false, true);
            if (this._targetEntity == null || !_loc_2)
            {
                this.stop();
            }
            return;
        }// end function

        private function forceUpdated(param1 = null) : void
        {
            this.stop();
            return;
        }// end function

        private function buffUpdateHandler(param1) : void
        {
            var _loc_2:* = Cache.instance.skill.getFirstSkill();
            if (_loc_2 == null)
            {
                return;
            }
            if (!BuffUtil.isCanRoleFireSkill(_loc_2))
            {
                this.stop();
            }
            return;
        }// end function

        protected function onPlayerDeadHandler(event:Event) : void
        {
            this.stop();
            return;
        }// end function

        protected function onEntityDead(event:Event) : void
        {
            this.stop();
            return;
        }// end function

        override public function stop(param1:Boolean = true) : void
        {
            this.cancelAll();
            if (this._targetEntityInfo)
            {
                this._targetEntityInfo.removeEventListener(EntityInfoEventName.UpdateForce, this.forceUpdated);
                this._targetEntityInfo.removeEventListener(EntityInfoEventName.UpdateFightMode, this.forceUpdated);
                this._targetEntityInfo = null;
            }
            if (this._targetEntity != null)
            {
                FrEventDispatcher.instance.proxyRemoveEventListener(this._targetEntity, PlayerEvent.ENTITY_DEAD, this.onPlayerDeadHandler);
                FrEventDispatcher.instance.proxyRemoveEventListener(RolePlayer.instance, PlayerEvent.ENTITY_DEAD, this.onEntityDead);
            }
            if (this._timer != null)
            {
                this._timer.stop();
                this._timer = null;
            }
            this._skill = null;
            this._targetEntity = null;
            this._cd = null;
            NetDispatcher.removeCmdListener(ServerCommand.BufferUpdate, this.buffUpdateHandler);
            super.stop(param1);
            return;
        }// end function

        public function useSkill(param1:SkillInfo) : void
        {
            this._skillTobeUseFirtst = param1;
            this.onEnterFrameHandler();
            return;
        }// end function

        private function updateSkill() : void
        {
            if (this._skillTobeUseFirtst != null)
            {
                this._skill = this._skillTobeUseFirtst;
                this._skillTobeUseFirtst = null;
                return;
            }
            if (Cache.instance.skill.isShowingExSkill)
            {
                this._skill = Cache.instance.skill.getExtSkillByPosType(1);
            }
            else
            {
                this._skill = Cache.instance.skill.getSkillByPosType(1);
            }
            return;
        }// end function

        private function onEnterFrameHandler(param1 = null) : void
        {
            var _loc_4:Point = null;
            var _loc_5:Point = null;
            var _loc_6:Point = null;
            if (RolePlayer.instance.isInSpasticity || PetBreakCopyUtil.player.entityInfo == null || PetBreakCopyUtil.player.entityInfo.isDead)
            {
                return;
            }
            if (this._curAI != null && this._skillTobeUseFirtst == null)
            {
                return;
            }
            if (this._cd != null && this._cd.isCoolDown)
            {
                return;
            }
            if (this._targetEntity.entityInfo == null || this._targetEntity.entityInfo.entityInfo == null)
            {
                return;
            }
            if (this._targetEntity.entityInfo.entityInfo.life <= 0)
            {
                this.stop();
                return;
            }
            this.updateSkill();
            if (this._skill == null)
            {
                return;
            }
            if (this._skill.tSkill.consume > this.roleInfo.mana)
            {
                MsgManager.showRollTipsMsg(Language.getStringByParam(20606, this._skill.tSkill.name));
                return;
            }
            if (!BuffUtil.isCanRoleFireSkill(this._skill))
            {
                MsgManager.showRollTipsMsg(Language.getStringByParam(20607, this._skill.tSkill.name));
                return;
            }
            ThingUtil.selectEntity = this._targetEntity;
            var _loc_2:* = AIFactory.instance.outFollowFightAIData();
            _loc_2.skillInfo = this._skill;
            FightUtil.selectEntityBySkill(_loc_2, Cache.instance.shortcut.isLastKeyByClick);
            if (_loc_2.target == null)
            {
                ThingUtil.selectEntity = null;
            }
            if (_loc_2.target == null && _loc_2.point == null)
            {
                AIFactory.instance.inFollowFightAIData(_loc_2);
                return;
            }
            var _loc_3:* = this._targetEntity;
            if (!SkillUtil.canMapUseSkill(this._skill, _loc_2))
            {
                return;
            }
            if (_loc_2.isSkillThenWalk)
            {
                if (!PetBreakCopyUtil.player.entityInfo.fighting)
                {
                    return;
                }
                this.cancelAll();
                _loc_4 = new Point(_loc_2.point.x, _loc_2.point.y);
                _loc_5 = GeomUtil.getPointByDistance(PetBreakCopyUtil.player.x2d, PetBreakCopyUtil.player.y2d, _loc_2.point.x, _loc_2.point.y, _loc_2.range - 20);
                _loc_2.point.x = _loc_5.x;
                _loc_2.point.y = _loc_5.y;
                this.addFightOnce(_loc_2);
                this.addCallback(SkillController.skillThenWalkCallback, [_loc_4, 50]);
                this.startAIList();
                return;
            }
            else if (_loc_2.target != null)
            {
                if (_loc_2.target is MonsterPlayer && BossRule.isCollectBoss(_loc_2.target as MonsterPlayer))
                {
                    _loc_3 = _loc_2.target as MonsterPlayer;
                    if (_loc_3.entityID == Cache.instance.skill.waittingServerCollectID || !BossRule.isBossTypeCanSelect((_loc_2.target as MonsterPlayer).bossInfo.type))
                    {
                        AIFactory.instance.inFollowFightAIData(_loc_2);
                        return;
                    }
                    this.cancelAll();
                    this.addMoveTo(new Point(_loc_3.x2d, _loc_3.y2d), _loc_3.entityInfo.bodySize + RolePlayer.instance.entityInfo.bodySize);
                    this.addCollectAI(_loc_3 as MonsterPlayer);
                    this.startAIList();
                    return;
                }
                else
                {
                    this.cancelAll();
                    if (GeomUtil.calcDistance(RolePlayer.instance.x2d, RolePlayer.instance.y2d, _loc_3.x2d, _loc_3.y2d) >= 500)
                    {
                        this.addMoveTo(new Point(_loc_3.x2d, _loc_3.y2d), _loc_2.range + 100);
                    }
                    this.addFollowFight(_loc_2);
                    this.startAIList();
                    return;
                }
            }
            else if (_loc_2.point != null)
            {
                if (!PetBreakCopyUtil.player.entityInfo.fighting)
                {
                    return;
                }
                this.cancelAll();
                _loc_6 = new Point(_loc_2.point.x, _loc_2.point.y);
                this.addMoveTo(_loc_6, _loc_2.range);
                this.addFollowFight(_loc_2);
                this.startAIList();
                return;
            }
            return;
        }// end function

        public function addCallback(param1:Function, param2:Object = null) : void
        {
            var _loc_3:* = new CallBackData();
            _loc_3.meRole = PetBreakCopyUtil.player;
            _loc_3.scene = Game.scene;
            var _loc_4:* = new CallBackAI();
            _loc_4.data = _loc_3;
            _loc_3.callback = param1;
            _loc_3.params = param2;
            this._aiList.push(_loc_4);
            return;
        }// end function

        public function addFightOnce(param1:FollowFightAIData) : void
        {
            var _loc_2:* = new FightOnceAI();
            _loc_2.data = param1;
            this._aiList.push(_loc_2);
            return;
        }// end function

        public function addFollowFight(param1:FollowFightAIData) : void
        {
            var _loc_2:IAICommand = null;
            if (param1.skillInfo == null)
            {
                param1.skillInfo = Cache.instance.skill.getFirstSkill();
                if (param1.skillInfo == null)
                {
                    return;
                }
            }
            _loc_2 = new FollowFightAI();
            _loc_2.data = param1;
            this._aiList.push(_loc_2);
            return;
        }// end function

        public function addCollectAI(param1:MonsterPlayer) : void
        {
            var _loc_2:* = new CollectAI();
            var _loc_3:* = AIFactory.instance.outAIData();
            _loc_3.target = param1;
            _loc_2.data = _loc_3;
            this._aiList.push(_loc_2);
            return;
        }// end function

        public function cancelAll() : void
        {
            if (this._curAI != null)
            {
                this._isCancelAll = true;
                AIFactory.instance.inAIData(this._curAI.data);
                this._curAI.stop();
                this._curAI = null;
                this._isCancelAll = false;
            }
            this.inPoolAllTobeStartAi();
            return;
        }// end function

        public function startAIList() : void
        {
            if (this._isCancelAll)
            {
                return;
            }
            if (this._curAI != null)
            {
                AIFactory.instance.inAIData(this._curAI.data);
                this._curAI = null;
            }
            if (this._aiList.length == 0)
            {
                return;
            }
            this._curAI = this._aiList.shift();
            this._curAI.start(this.startAIList);
            return;
        }// end function

        public function inPoolAllTobeStartAi() : void
        {
            var _loc_2:IAICommand = null;
            if (this._aiList.length == 0)
            {
                return;
            }
            var _loc_1:int = 0;
            while (_loc_1 < this._aiList.length)
            {
                
                _loc_2 = this._aiList[_loc_1];
                AIFactory.instance.inAIData(_loc_2.data);
                _loc_1++;
            }
            this._aiList = [];
            return;
        }// end function

        public function addMoveTo(param1:Point, param2:int = -1, param3:Boolean = false) : void
        {
            var _loc_6:AstarTurnPoint = null;
            var _loc_7:Array = null;
            var _loc_9:Object = null;
            var _loc_10:int = 0;
            var _loc_4:* = new Point(RolePlayer.instance.x2d, RolePlayer.instance.y2d);
            var _loc_5:* = Scene3DClickProcessor.findPath(_loc_4.x, _loc_4.y, param1.x, param1.y, true);
            if (_loc_5 == null || _loc_5.length <= 0)
            {
                return;
            }
            var _loc_8:int = 0;
            while (_loc_8 < _loc_5.length)
            {
                
                _loc_9 = _loc_5[_loc_8];
                if (_loc_9 is AstarTurnPoint)
                {
                    _loc_6 = _loc_9 as AstarTurnPoint;
                    this.addJump(new Point(_loc_6._x + 0.5, _loc_6._y + 0.5), param3);
                }
                else
                {
                    _loc_10 = 0;
                    if (_loc_8 == (_loc_5.length - 1))
                    {
                        _loc_10 = param2;
                    }
                    this.addMoveByPath(_loc_9 as Array, _loc_10, param3);
                }
                _loc_8++;
            }
            return;
        }// end function

        public function addJump(param1:Point, param2:Boolean = false) : void
        {
            var _loc_3:* = new JumpAI();
            var _loc_4:* = AIFactory.instance.outAIData();
            _loc_3.data = _loc_4;
            _loc_4.target = param1;
            if (param2)
            {
                this._aiList.unshift(_loc_3);
            }
            else
            {
                this._aiList.push(_loc_3);
            }
            return;
        }// end function

        public function addMoveByPath(param1:Array, param2:int = -1, param3:Boolean = false) : void
        {
            var _loc_4:* = new MoveByPathAI();
            var _loc_5:* = AIFactory.instance.outAIData();
            _loc_4.data = _loc_5;
            _loc_5.params = param1;
            if (param2 != -1)
            {
                MoveByPathAI(_loc_4).range = param2;
            }
            if (param3)
            {
                this._aiList.unshift(_loc_4);
            }
            else
            {
                this._aiList.push(_loc_4);
            }
            return;
        }// end function

    }
}
